package com.omg.server.crawler.strategy.impl;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.HTMLElementName;
import net.htmlparser.jericho.Source;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.omg.business.model.PostMeta;
import com.omg.business.model.Posts;
import com.omg.business.model.Terms;
import com.omg.business.model.TermsRelation;
import com.omg.business.model.TermsTaxonomy;
import com.omg.server.crawler.RequestContext;
import com.omg.server.crawler.strategy.CrawlerStrategy;
import com.omg.server.framework.service.IDefaultService;
import com.omg.server.util.CommonUtil;
import com.omg.server.util.DateUtil;
import com.omg.weibo.WeiBoSender;
/**
 * 买个便宜货 美国便宜货 网站抓取策略
 * @author Administrator
 */
public class MoneyStrategyImpl implements CrawlerStrategy{
	private static final Log log = LogFactory.getLog(SmzdmStrategyImpl.class);
	private IDefaultService defaultService;
	@Override
	public void handle(RequestContext requestContext) {
		int pageIndex = requestContext.getStartIndex();
		if(pageIndex < 1){
			return;
		}
		String url = requestContext.getSiteUrl();
		String soureUrl = requestContext.getSiteUrl();
		if (CommonUtil.isEmpty(url)){
			return;
		}
		if (pageIndex >= 1){
			url +="page/"+pageIndex;
		}
		Source source = null;
		try {
			String subStract = null;
			String imgUrl = null;
			String imgUrl2 = null;
			String targetUrl = null;
			Element subElement = null;
			List<Element> linkList = null;
			Element subElement2 = null;
			String priceInfo = null;
			String issueTime = null;
			String type = null;
			String tag = null;
			String linkContent = null;
			Posts posts = null;
			PostMeta postMeta = null;
			PostMeta postMeta2 = null;
			String tmpStr = null;
			source = new Source(new URL(url));
			int currentYear = Calendar.getInstance().get(Calendar.YEAR);
			// Call fullSequentialParse manually as most of the source will be parsed.
			source.fullSequentialParse();
			int mIndex = -1;
			String price = null;
			String title = null;
			Date issueDate = null;
			HashSet<PostMeta> pmSet = new HashSet<PostMeta>(2);
			Map<String, Object> params = new HashMap<String, Object>(2);
			List<Integer> count = null;
			Date lastReleaseDate = null;
			List<Element> goodList = source.getAllElementsByClass("post type-post status-publish format-standard hentry category-cxkx");
			if (CommonUtil.isNotEmpty(goodList)){
				List<Element> comElemnets = null;
				WeiBoSender wbs = new WeiBoSender();
				for (Element el: goodList){
					try{
						subStract = null;
						targetUrl = null;
						posts = new Posts();
						postMeta = new PostMeta();
						postMeta2 = new PostMeta();
						subElement = el.getFirstElementByClass("time");
						issueTime = subElement.getTextExtractor().toString();
						issueDate = DateUtil.convertToDate(issueTime, DateUtil.PATTERN_MMDD);
						if (null != issueDate){
							if (null == lastReleaseDate || issueDate.after(lastReleaseDate)){
								lastReleaseDate = issueDate;
							}
						}
						subElement = el.getFirstElementByClass("meta");
						if(null != subElement){
							subElement = subElement.getFirstElement(HTMLElementName.A);
							if(null != subElement){
								type = subElement.getTextExtractor().toString();
								tag = type;
							}
						}
						subElement = el.getFirstElementByClass("content");
						comElemnets = subElement.getAllElements(HTMLElementName.A);
						if (CommonUtil.isNotEmpty(comElemnets) && comElemnets.size() > 2){
							priceInfo = comElemnets.get(0).getTextExtractor().toString();//价格信息
							mIndex = priceInfo.indexOf("$");
							if (mIndex > -1){
								price = priceInfo.substring(mIndex);
								title = priceInfo.replace(price, "");
							}
							posts.setPostTitle(title);
							targetUrl = comElemnets.get(1).getAttributeValue("href");//商品目标地址
							subElement2 = comElemnets.get(2).getFirstElement(HTMLElementName.IMG);
							if (null != subElement2){
							    imgUrl = subElement2.getAttributeValue("src");//商品图片地址
							    /*if (null !=imgUrl && imgUrl.indexOf(soureUrl) < 0){
									if (imgUrl.startsWith("/")){
									   imgUrl = soureUrl.substring(0, soureUrl.length()-1) + imgUrl;
									}
									else{
										imgUrl = soureUrl + imgUrl;
									}
								}*/
							}
							subElement2 = subElement.getFirstElement(HTMLElementName.H2);
							tmpStr = subElement2.getContent().toString();
							List<Element> imgsList = subElement.getAllElements(HTMLElementName.IMG);
							subStract = subElement.getContent().toString();//商品摘要
							linkList = subElement.getAllElements(HTMLElementName.A);
							if (CommonUtil.isNotEmpty(linkList) && null != subStract){
								for (Element cl : linkList){
									linkContent = cl.getTextExtractor().toString();
									subStract = subStract.replace(cl.toString(), linkContent);
								}
							}
							
							if (null != tmpStr){
								subStract = subStract.replace("<h2>"+tmpStr+"</h2>", "");
								for (Element e : imgsList){
									subStract = subStract.replace(e.getContent().toString(), "");
								}
							}
							subStract.replaceAll(soureUrl, "www.buymefan.com");
							List<Element> imgsList2 = subElement.getAllElements(HTMLElementName.IMG);
							if(null != imgsList2)
							for (Element e : imgsList2){
								if (CommonUtil.isEmpty(imgUrl2)){
									imgUrl2 = e.getAttributeValue("src");
									
								}
								subStract = subStract.replace(e.toString(), "");
							}
							if (CommonUtil.isNotEmpty(issueTime)) {
					                issueTime = issueTime.trim();
							}
							if (CommonUtil.isEmpty(issueTime)){
								if (null == lastReleaseDate){
									continue;
								}
								else{
									issueTime =  DateUtil.formatDate(lastReleaseDate, DateUtil.PATTERN_MMDD);
								}
							}
							//System.out.println("issueTime: " + issueTime);
				            issueTime = issueTime + " " + DateUtil.formatDate(new Date(), DateUtil.HHMM);
							issueDate = DateUtil.convertToDate(issueTime, DateUtil.PATTERN_MMDDHHMM);
							if (null != requestContext.getMaxDate() && null != issueDate){
								if (issueDate.before(requestContext.getMaxDate())){
									continue;
								}
							}
							
							if (null != issueDate){
								posts.setPostDate(issueDate);
								posts.setPostDate2(issueDate);
								posts.setPostModified(issueDate);
								posts.setPostModified2(issueDate);
							}
							else{
								continue;
							}
							
							targetUrl = CommonUtil.getFinalUrl(targetUrl);
							if (null != targetUrl){
								if (targetUrl.contains(soureUrl)){
									continue;
								}
								if (targetUrl.startsWith("ttp://")){
									targetUrl = "h" + targetUrl;
								}
							    //targetUrl = URLDecoder.decode(targetUrl);
							}
							//检查库中是否有这样的数据
							params.put("title", title);
							params.put("soureUrl", soureUrl);
							params.put("targetUrl", targetUrl);
							count = defaultService.find_iBatis("omg.crawler.checkGoodsIsExist", params);
							if (CommonUtil.isNotEmpty(count)){
								if (count.get(0) > 0){
									continue;
								}
							}
							
							postMeta.setMetaKey("thumbnail");
							if(CommonUtil.isEmpty(imgUrl)){
								imgUrl = imgUrl2;
							}
							postMeta.setMetaValue(imgUrl);
							
							posts.setSourceUrl(soureUrl);
							posts.setPostContent(subStract);
							posts.setPostName(title);
							postMeta2.setMetaKey("targeturl");
							postMeta2.setMetaValue(targetUrl);
							//postMeta.setId(UUID.randomUUID().toString());
							//postMeta2.setId(UUID.randomUUID().toString());
							if(null != price && price.matches("[\\d.]+") && price.indexOf("元") < 0){
								price += "元";
							}
							posts.setPrice(price);
							
							if (CommonUtil.isNotEmpty(title) && CommonUtil.isNotEmpty(subStract) && CommonUtil.isNotEmpty(targetUrl)){
								pmSet.add(postMeta);
								pmSet.add(postMeta2);
								//posts.setPostMetas(pmSet);
							    //defaultService.save_Hibernate_Object(posts);
							    WriteDBUtil.writeToDb(posts, pmSet, type, tag,"、 ", "、",imgUrl, wbs);
								pmSet.clear(); //清空扩展
								/*
							    postId = posts.getId();
							    if (postId <= 0){
							    	log.debug("生成的post_id 为:" + postId);
							    }
							    pmSet.clear();
							    
							    this.saveCataAndTag(type, tag, postId);
								log.info(url + "商品录入成功.");
								if ("1".equals(PropertiesHelper.getProperty(ISSENDWEIBO))){
							        //发送微博
							        wbs.send(title, imgUrl, CrawlerStrategy.SITEURL+postId);
							    }*/
							}
							
					    }
					}
				    catch(Exception e){
				    	log.error(e);
				    }
					finally{
						 pmSet.clear(); //清空扩展
					}
				}
				
			}
		}
		catch (MalformedURLException e) {
			log.error(e);
		} 
		catch (IOException e) {
			log.error(e);
		}
	}
	private void saveCataAndTag(String type, String tag, int postId){
    	Map<String, String> params = new HashMap<String,String>();
    	List<Integer> termTaxonomy = null;
    	int cataTermTaxonomyId = -1;
    	int tagTermTaxonomyId = -1;
    	
    	if (CommonUtil.isEmpty(type)){
			type = "其它";
		}
		else{
			type = type.trim();
		}
		
		
		String[] types = type.split("、 ");
		TermsRelation termsRelation = null;
		TermsTaxonomy termsTaxonomy = null;
		Terms terms = null;
		for (int i=0, len=types.length; i < len; i++){
			cataTermTaxonomyId = -1;
			//检查目录是否存在
			params.clear();
			params.put("taxonomy", "category");
			params.put("termName", types[i]);
			termTaxonomy = defaultService.find_iBatis("omg.post.checkTermsIsExist", params);
			if (CommonUtil.isNotEmpty(termTaxonomy)){
				cataTermTaxonomyId = termTaxonomy.get(0);
			}
			
			//保存分类目录
			termsRelation = new TermsRelation();
			if (-1 == cataTermTaxonomyId){
				terms = new Terms();
				terms.setName(types[i]);
				terms.setSlug(URLEncoder.encode(types[i]));
				defaultService.save_Hibernate_Object(terms);
				termsTaxonomy = new TermsTaxonomy();
				termsTaxonomy.setTermId(terms.getId());
				termsTaxonomy.setTaxonomy("category");
				termsTaxonomy.setDescription("商品分类目录");
				defaultService.save_Hibernate_Object(termsTaxonomy);
				cataTermTaxonomyId = termsTaxonomy.getId();
			}
			termsRelation.setId(postId);
			termsRelation.setTermOrder(i);
			termsRelation.setTermTaxonomyId(cataTermTaxonomyId);
			defaultService.save_Hibernate_Object(termsRelation);
			log.debug("商品分类目录成功:" +postId);
		}
		if (CommonUtil.isNotEmpty(tag)){
			String[] tags = tag.split("、");
			for (int i=0,len=tags.length;i < len; i++){
				
				tagTermTaxonomyId = -1;
				//检查标签是否已存在
				params.clear();
				params.put("taxonomy", "post_tag");
				params.put("termName", tags[i]);
				termTaxonomy = defaultService.find_iBatis("omg.post.checkTermsIsExist", params);
				if (CommonUtil.isNotEmpty(termTaxonomy)){
					tagTermTaxonomyId = termTaxonomy.get(0);
				}
				try{
					//保存标签
					termsRelation = new TermsRelation();
					if (-1 == tagTermTaxonomyId){
					   terms = new Terms();
					   terms.setName(tags[i]);
					   terms.setSlug(URLEncoder.encode(tags[i]));
					   defaultService.save_Hibernate_Object(terms);
					   termsTaxonomy = new TermsTaxonomy();
					   termsTaxonomy.setTermId(terms.getId());
					   termsTaxonomy.setTaxonomy("post_tag");
					   termsTaxonomy.setDescription("商品标签");
					   defaultService.save_Hibernate_Object(termsTaxonomy);
					   tagTermTaxonomyId = termsTaxonomy.getId();
					}
					termsRelation.setId(postId);
					termsRelation.setTermOrder(i);
					termsRelation.setTermTaxonomyId(tagTermTaxonomyId);
					defaultService.save_Hibernate_Object(termsRelation);
					log.debug("商品标签成功:" +postId);
				}
				catch(Exception e){
					e.printStackTrace();
				}
		    }
		}
    }
	public IDefaultService getDefaultService() {
		return defaultService;
	}
	public void setDefaultService(IDefaultService defaultService) {
		this.defaultService = defaultService;
	}
	
	public static void main(String[] args){
		RequestContext requestContext = new RequestContext();
		requestContext.setStartIndex(2);
		requestContext.setSiteUrl("http://www.51money.info/");
		new MoneyStrategyImpl().handle(requestContext);
	}

}
